<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/9/5
 * Time: 13:57
 */

namespace app\index\controller;

use app\index\model\Address;
use app\index\model\M;
use app\index\model\BySale;
use app\index\model\Sale as SaleModel;
use app\index\model\Product as ProductModel;
use app\index\model\ProductInfo as ProductInfoModel;
use app\index\model\ProductInfo;
use app\index\model\User as UserModel;
use app\index\server\LoginRegServer;
use app\index\validate\IDMustBePostiveInt;
use think\cache\driver\Redis;

class Cart extends Auth
{
    private $redis;
    private $username;

    public function _initialize()
    {
        $this->redis = new Redis();
        $this->model = new M();
	    //session('Auth.Uid', 11);
	    //session('Auth.Username', 'rough');
        if(!session('Auth.Username')) {
            // 获取 openid 如果 openid 在数据库中不存在 则跳转到注册页面
            $loginServer = new LoginRegServer();
            return $loginServer->login('cart');
        } else {
            $this->username = session('Auth.Username');
        }
    }

    // 用 redis 操作购物车数据
    // 将商品加入 redis 中
    public function addToCart()
    {
        (new IDMustBePostiveInt())->goCheck();
        // 商品id
        $gid = input('post.id');
        $cartNum = input('post.num');
        if(!$cartNum) {
            $cartNum = 1;
        }
        $product_info = ProductInfoModel::find($gid);
        var_dump($product_info);die;
        if(!$product_info) {
            return setMsg(0, '非常抱歉,商品不存在发生错误');
        }
        // 商品的详细信息(从数据库中获取)
        $stock = $product_info->stock;
        if($stock < 1 || $stock < $cartNum) {
            return setMsg(0, '非常抱歉您选择的数量大于库存量');
        }
        // 商品有优惠需要查询优惠表
        $product_id = $product_info->product_id;
        // 查询此用户是否有优惠
        $product_table = ProductModel::where('sale_id', '>', 0)
            ->where('id', $product_id)
            ->find();
        if($product_table) {
            // 有优惠需要查询 sy_sale表
            $sale = SaleModel::where('id', $product_table->sale_id)
                ->where('status', '=', 1)
                ->find();
            // 查看已经购买的数量
            $num = BySale::where('uid', session('Auth.Uid'))
                ->where('sale_id', $sale->id)
                ->where('product_id', $product_id)
                ->where('is_pay', '=', 1)
                ->sum('num');
            if($num >= $sale->max){
                return setMsg(0, '非常抱歉 您已享受过该优惠 如有疑问 请联系客服');
            }
            // 获取当前 此商品的数量
            // 查询此 product_id 的所有的商品 id
            $id_arr = ProductInfoModel::where('status', '=', 1)
                ->where('product_id', '=', $product_id)
                ->column('id');
            $num = 0;
            foreach ($id_arr as $value) {
                $num += $this->redis->hGet($this->username . ':' . $value, 'num');
            }
//            return setMsg(0, $num);die;
            if($num >= $sale->max) {
                return setMsg(0, '非常抱歉,您所购买的商品到达该商品最大限购数量');
            }
        }
        $goodData = [
            'id' => $product_info->id,
            'price' => $product_info->price,
            'member_price' => $product_info->member_price,
            'size' => $product_info->size,
            'color' => $product_info->color,
            'url' => $product_info->url,
            'select' => 1,
        ];
        // 写入 redis key为 username:商品id
        $key = $this->username . ':' . $gid;
        // 判断是否存在此用户的此商品 格式为 username:商品id
        $data = $this->redis->exists($key);
        // 判断购物车中是否有无商品，然后根据情况加入购物车
        if (!$data) {
            // 新增购物车数据
            // 商品总数量 格式为 username:counts 不存在则设置
            $counts_key = $this->username . ':' . 'counts';
            if(!$this->redis->exists($counts_key)) {
                $this->redis->setNx($counts_key, $cartNum);
            } else {
                $this->redis->incrBy($counts_key, $cartNum);
            }
            // 当前商品数量
            $goodData['num'] = $cartNum;
            // 将商品数据存放到redis中hash
            $this->redis->hmset($key, $goodData);
            $s_key = $this->username . ':'. 'sAdd';
            // 将商品ID存放集合中,是为了更好将用户的购物车的商品给遍历出来
            $this->redis->sadd($s_key, $gid);
        } else {
            $this->redis->incrBy($this->username . ':counts', $cartNum);
            // 购物车有对应的商品，添加对应商品的数量
            $originNum = $this->redis->hget($key, 'num');
            // 原来的数量加上用户新加入的数量
            $newNum = $originNum + $cartNum;
            $this->redis->hset($key, 'num', $newNum);
        }
        return setMsg(1, '添加到购物车成功');
    }

    // 显示用户购物车的所有商品
    public function showCartList($flag = 0)
    {
        $key = $this->username . ':'. 'sAdd';
        $cart_all = [];
        // 先根据集合拿到商品ID
        $idArr =  $this->redis->sMembers($key);
        // 没有商品 空购物车的页面
        if(!$idArr) {
            return $this->fetch('cart/cart_empty');
        }
        // 判断是否已经选中的商品(下订单页面)
        if($flag) {
            // 订单页面
            for ($i = 0; $i < count($idArr); $i++) {
                $k  = $this->username . ':' . $idArr[$i];
                $is_select = $this->redis->hGet($k, 'select');
                if($is_select) {
                    $cart_all[$idArr[$i]] = $this->redis->hGetAll($k);
                }
            }
        } else {
            // 购物车页面 所有
            for ($i = 0; $i < count($idArr); $i++) {
                $k  = $this->username . ':' . $idArr[$i];
                $cart_all[$idArr[$i]] = $this->redis->hGetAll($k);
            }
        }
        $product_info = ProductInfo::where('id', 'in', $idArr)
            ->select();
        $checked_all = 1;
        $count_price = 0; // 总价格
        $all_num = 0; // 商品总数量(选中)
        $is_vip = session('Auth.IsVIP');
        $to_pay = 0;
        foreach($product_info as $key => $value) {
            $id = $value->id;
//            dump($value->toArray());
//            dump($value->stock);
            if($value->status == 0) {
                // 商品下架直接删除此商品
                $this->delProduct($id);
            }
            if($value->stock < $cart_all[$id]['num']) {
                // 库存量 < 购买量则强行讲 购买量减为 库存量
                $this->addOrReduceInfo($this->username . ':' . $id, $value->stock);
                $cart_all[$id]['num'] = $value->stock;
            }
            if($value->stock <= 0) {
                // 卖光了所有的货物 库存量为 0
                $this->delProduct($id);
            }
            if($cart_all[$id]['select'] == 0) {
                $checked_all = 0;
            } else {
                $to_pay = 1;
                $all_num += (int)$cart_all[$id]['num'];
            }
            $member_price = $value->member_price;
            $price = $value->price;
            $cart_all[$id]['price'] = $price;
            $cart_all[$id]['member_price'] = $member_price;
            $cart_all[$id]['stock'] = $value->stock;
            $cart_all[$id]['description'] = $value->description;
            $cart_all[$id]['name'] = $value->name;
            $is_select = $cart_all[$id]['select'];
            if($is_select) {
                if($is_vip) {
                    $count_price += $member_price * 100 * $cart_all[$id]['num'];
                } else {
                    $count_price += $price * 100 * $cart_all[$id]['num'];
                }
            }
        }
        $count = (float)$count_price/100;
        $this->assign('count_price', $count);
        $this->assign('pay', $to_pay);
        $this->assign('all_num', $all_num);
        $this->assign('checked_all', $checked_all);
        $this->assign('product_list', $cart_all);
        return $this->fetch('cart/product_list');
    }

    public function cart_empty()
    {
        return $this->fetch();
    }

    // 统计购物车内选中的个数
    public function selected()
    {
        // 遍历 sAdd 集合拿到这些数据的 id
        $s_key = $this->username . ':'. 'sAdd';
        $idArr =  $this->redis->sMembers($s_key);
        $selected_num = 0;
        for ($i = 0; $i < count($idArr); $i++) {
            $k  = $this->username . ':' . $idArr[$i];
            $select_result = $this->redis->hGet($k, 'select');
            if($select_result == 1) {
                $selected_num += 1;
            }
        }
        return $selected_num;
    }

    // 删除购物车内的商品
    public function delCartProduct($id)
    {
        (new IDMustBePostiveInt())->goCheck();
        // 在 redis 中的 key
        $key = $this->username . ':' . $id;
        // 获取此商品的数量 计算总数量
        $product_info = $this->redis->hget($key, 'num');
        // 减去总数量
        $count_result = $this->redis->incrBy($this->username . ':counts', '-' . $product_info);
        // 为 0 时就删除这一条数据
        if($count_result <= 0) {
            $this->redis->del($this->username . ':counts');
        }
        // 删除此单品的数据
        $this->redis->del($key);
        // 移除集合中的单品 id
        $s_key = $this->username . ':' . 'sAdd';
        $del_s_product = $this->redis->sRem($s_key, $id);
        // 删除这个数据
        if($del_s_product === '') {
            $this->redis->del($this->username . ':sAdd');
        }
        return setMsg(1, '删除此数据成功');
    }

    public function delProduct($id)
    {
        $key = $this->username . ':' . $id;
        // 获取此商品的数量 计算总数量
        $product_info = $this->redis->hget($key, 'num');
        // 减去总数量
        $count_result = $this->redis->incrBy($this->username . ':counts', '-' . $product_info);
        // 为 0 时就删除这一条数据
        if($count_result <= 0) {
            $this->redis->del($this->username . ':counts');
        }
        // 删除此单品的数据
        $this->redis->del($key);
        // 移除集合中的单品 id
        $s_key = $this->username . ':' . 'sAdd';
        $del_s_product = $this->redis->sRem($s_key, $id);
        // 删除这个数据
        if($del_s_product === '') {
            $this->redis->del($this->username . ':sAdd');
        }
    }


    // 获取商品总数量
    public function counts()
    {
        return $this->redis->get($this->username . ':counts');
    }

    // 改变选中状态
    public function changSelect()
    {
        $key = $this->username . ':' . input('post.id');
        $select = (input('post.status') == 1) ? 0 : 1;
        $this->redis->hset($key, 'select', $select);
        return setMsg(1, 'OK', $select);
    }

    // 全选或者全取消
    public function changeAll($type)
    {
        $select = ($type == 1) ? 0 : 1;
        // 遍历 sAdd 集合拿到这些数据的 id
        $s_key = $this->username . ':'. 'sAdd';
        $idArr =  $this->redis->sMembers($s_key);
        $selected = count($idArr);
        for ($i = 0; $i < count($idArr); $i++) {
            $k  = $this->username . ':' . $idArr[$i];
            $this->redis->hset($k, 'select', $select);
        }
        return ($type == 1) ? 0 : $selected;
    }

    // 商品的加减 还需要更新总的 counts
    public function addOrReduce()
    {
        $id = input('post.id');
        // 查看是否超标
        $product_info = ProductInfo::find($id);
        if(!$product_info) {
            return setMsg(0, '没有找到此商品');
        }


        // 商品有优惠需要查询优惠表
        $product_id = $product_info->product_id;
        // 查询此商品是否有优惠
        $product_table = ProductModel::where('sale_id', '>', 0)
            ->where('id', $product_id)
            ->find();
        if($product_table) {
            // 有优惠需要查询 sy_sale表
            $sale = SaleModel::where('id', $product_table->sale_id)
                ->where('status', '=', 1)
                ->find();
            // 获取当前 此商品的数量
            $num = $this->redis->hGet($this->username . ':' . $id, 'num');
            // 获取用户已经购买的数量
            $buy_num = BySale::where('is_pay', '=', 1)
                ->where('product_id', $product_id)
                ->where('uid', session('Auth.Uid'))
                ->sum('num');
            if(($num >= $sale->max) || $buy_num >= $sale->max) {
                return setMsg(0, '非常抱歉,您所购买的商品到达该商品最大限购数量');
            }
        }



        $key = $this->username . ':' . $id;
        $cartNum = (input('post.type') == 'add') ? 1 : -1;
        // 购物车有对应的商品，添加对应商品的数量
        $originNum = $this->redis->hget($key, 'num');
        if(($originNum >= $product_info->stock) && $cartNum > 0) {
            return setMsg(0, '商品数量已经为最大库存,不能再增加商品');
        }
        if($originNum <= 1 && $cartNum == -1) {
            return setMsg(0, '商品最低只能减到1');
        }
        // 原来的数量加上用户新加入的数量
        $newNum = $originNum + $cartNum;
        $this->redis->hset($key, 'num', $newNum);
        $result = $this->redis->incrBy($this->username . ':counts', $cartNum);
        if(!$result) {
            return setMsg(0, '改变商品数量失败');
        }
        return setMsg(1, '改变商品数量成功');
    }

    public function addOrReduceInfo($key, $cartNum)
    {
        $originNum = $this->redis->hget($key, 'num');
        if($originNum <= 1 && $cartNum == -1) {
            return ['message'=> '最低只能减到1'];
        }
        // 原来的数量加上用户新加入的数量
        $newNum = $originNum + $cartNum;
        $hset = $this->redis->hset($key, 'num', $newNum);
        if($hset) {
            $res = $this->redis->incrBy($this->username . ':counts', $cartNum);
            if($res) {
                return setMsg(1, 'OK');
            }
            return setMsg(0, '修改数量失败');
        }
    }

    // 确认支付信息
    public function payment()
    {
        // 获得收获地址信息
        $address = $this->address();
        // 获得选中信息
        $productAll = $this->productAll();
        if($address) {
            $this->assign('address', $address);
        }
        $uid = session('Auth.Uid');
        $Coupon = $this->model->selectWhere('sy_coupon','uid',$uid);
        $this->assign('product_all', $productAll['cart_all']);
        $this->assign('all_num', $productAll['all_num']);
        $this->assign('count_price', $productAll['count_price']);
        $this->assign('is_sale', $productAll['is_sale']);
        $this->assign('Coupon', $Coupon);
        return $this->fetch();
    }

    // 默认收货地址
    private function address()
    {
        $address_info = Address::where('status', '=', 1)
            ->where('default_address', '=', 1)
            ->where('user_id', session('Auth.Uid'))
            ->find();
        return $address_info;
    }

    public function productAll()
    {
        $all_num = 0;
        $is_vip = session('Auth.IsVIP');
        $count_price = 0;
        $key = $this->username . ':'. 'sAdd';
        $cart_all = [];
        // 先根据集合拿到商品ID
        $idArr =  $this->redis->sMembers($key);
        // 没有商品 空购物车的页面
        if(!$idArr) {
            return $this->redirect('myself/un_pay');
        }
        $select_idArr = []; // 选中的id
        for ($i = 0; $i < count($idArr); $i++) {
            $k  = $this->username . ':' . $idArr[$i];
            $is_select = $this->redis->hGet($k, 'select');
            if($is_select) {
                $cart_all[$idArr[$i]] = $this->redis->hGetAll($k);
                $select_idArr[] = $idArr[$i];
            }
        }
        $product_info = ProductInfo::where('id', 'in', $select_idArr)
            ->select();
        // 商品的 product_id_array
        $product_id_array = [];

        foreach($product_info as $key => $value) {
            $id = $value->id;

            $product_id_array[] = $value->product_id;

            if($value->status == 0) {
                // 商品下架直接删除此商品
                $this->delCartProduct($id);
            } else if($value->stock < $cart_all[$id]['num']) {
                // 库存量 < 购买量则强行讲 购买量减为 库存量
                $this->addOrReduceInfo($this->username . ':' . $id, $value->stock);
                $cart_all[$id]['num'] = $value->stock;
            }
            $all_num += (int)$cart_all[$id]['num'];
            $member_price = $value->member_price;
            $price = $value->price;
            $cart_all[$id]['price'] = $price;
            $cart_all[$id]['name'] = $value->name;
            $cart_all[$id]['description'] = $value->description;
            $cart_all[$id]['member_price'] = $member_price;
            if($is_vip) {
                $count_price += $member_price * 100 * $cart_all[$id]['num'];
                $cart_all[$id]['price'] = $member_price;
            } else {
                $cart_all[$id]['price'] = $price;
                $count_price += $price * 100 * $cart_all[$id]['num'];
            }
        }

        $product_id_array = array_unique($product_id_array);
        // 查看是否有优惠
        $sale_exists = ProductModel::where('id', 'in', $product_id_array)
            ->where('sale_id', '>', 0)
            ->count();
        return [
            'cart_all' => $cart_all,
            'all_num' => $all_num,
            'count_price' => $count_price/100,
            'is_sale' => $sale_exists
        ];
    }
}
